package com.xbongbong.paas.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasAppEntity;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.log.MongoLogHelp;
import com.xbongbong.paas.log.constant.LogMemoConstant;
import com.xbongbong.paas.model.PaasAppModel;
import com.xbongbong.paas.pojo.dto.ApplicationAddDTO;
import com.xbongbong.paas.pojo.dto.ApplicationUpdateDTO;
import com.xbongbong.paas.pojo.vo.ApplicationUpdateVO;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.redis.RedisConstant;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.service.ProAppService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.JsonHelperUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.pro.app.pojo.dto.ApplicationAddBatchDTO;
import com.xbongbong.pro.app.pojo.vo.ApplicationAddBatchVO;
import com.xbongbong.pro.enums.ValueAddedTypeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.menu.enums.SystemAppMenuEnum;
import com.xbongbong.pro.log.pojo.DetailLogPojo;
import com.xbongbong.saas.enums.OperateModuleTypeEnum;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.service.toolbox.help.LogHelp;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author 吴峰
 * @date 2022/10/28 14:01
 */
@Service("proAppService")
public class ProAppServiceImpl implements ProAppService {

    private static final Logger LOG = LoggerFactory.getLogger(ProAppServiceImpl.class);
    @Resource
    private PaasAppModel paasAppModel;
    @Resource
    private PaasRedisHelper paasRedisHelper;
    @Resource
    private MongoLogHelp mongoLogHelp;
    @Resource
    private LogHelp logHelp;

    @Override
    public ApplicationAddBatchVO addBatchPaasApp(ApplicationAddBatchDTO applicationAddBatchDTO) throws XbbException {
        ApplicationAddBatchVO applicationAddBatchVO = new ApplicationAddBatchVO();
        String corpid = applicationAddBatchDTO.getCorpid();
        String userId = applicationAddBatchDTO.getUserId();
        String userName = applicationAddBatchDTO.getLoginUserName();

        List<String> paasNameList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<PaasAppEntity> resultAppList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);

        try {
            // 校验自定义应用的套餐
            Map<String, Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            map.put("del", DelEnum.NORMAL.getDel());
            map.put("corpid", corpid);
            Integer count = paasAppModel.getEntitysCount(map);
            if(Objects.isNull(count)){
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
            }
            //市场管理app
            PaasAppEntity marketManagementApp = null;
            String marketManagementAlias = SystemAppMenuEnum.MARKET_MANAGEMENT.getAlias();
            List<PaasAppEntity> appList = new ArrayList<>();
            for (ApplicationAddDTO item : applicationAddBatchDTO.getAppList()) {
                PaasAppEntity paasAppEntity = new PaasAppEntity();
                paasAppEntity.setCorpid(corpid);
                BeanUtil.copyProperties(item, paasAppEntity);
                paasAppEntity.setSort(count++);
                long now = DateUtil.getInt();
                paasAppEntity.setCreatorId(userId);
                paasAppEntity.setAddTime(now);
                paasAppEntity.setUpdateTime(now);
                appList.add(paasAppEntity);
                paasNameList.add(item.getName());
                if(Objects.equals(paasAppEntity.getAlias(),marketManagementAlias)){
                    marketManagementApp  = paasAppEntity;
                }

            }
            resultAppList = paasAppModel.insertBatch(appList);
            //应用是市场管理的话，刷新缓存
            if(Objects.nonNull(marketManagementApp)){
                setEnable2RedisByAlias(corpid,marketManagementAlias,marketManagementApp.getEnable());
            }
            applicationAddBatchVO.setAppList(resultAppList);
            String key = corpid + "_"+ ValueAddedTypeEnum.CUSTOM_APPLICATION_NUM.getType();
            paasRedisHelper.removeValue(RedisPrefixConstant.VALUE_ADDED, key);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("paasApp数据库批量插入出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }

        // 记录日志
        if (Objects.equals(applicationAddBatchDTO.getCompanyInit(), 0)) {
            String paasNameStr = StringUtils.join(paasNameList, "，");
            String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_ADD_APP), userName, paasNameStr);
            mongoLogHelp.buildLog(corpid, userId, userName, OperateModuleTypeEnum.PAAS_APP, OperateTypeEnum.NEW,
                    "", "", memo, applicationAddBatchDTO.getHttpHeader());
        }

        return applicationAddBatchVO;
    }

    /**
     * 缓存
     * @param coprid
     * @param alias 应用对应的别名
     * @param enable 应用的启用状态。 1启用，0关闭
     * @throws XbbException
     */
    @Override
    public void setEnable2RedisByAlias(String coprid, String alias, Integer enable) throws XbbException {
        if(StringUtil.isNotEmpty(coprid) && StringUtil.isNotEmpty(alias) && Objects.nonNull(enable)){
            String key = coprid + "_" + alias;
            //缓存 应用的启用状态，时间为一周
            paasRedisHelper.setValue(RedisPrefixConstant.APP_ENABLE_STATUS, key,String.valueOf(enable), RedisConstant.HUGE_DURATION);
        }

    }


    @Override
    public ApplicationUpdateVO updatePaasApp(ApplicationUpdateDTO applicationUpdateDTO) throws XbbException {
        PaasAppEntity paasAppEntity = new PaasAppEntity();
        BeanUtil.copyProperties(applicationUpdateDTO, paasAppEntity, false);
        try {
            PaasAppEntity entity = paasAppModel.getByKey(applicationUpdateDTO.getId(), applicationUpdateDTO.getCorpid());
            if (entity == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.APP_NOT_EXIST);
            }
            paasAppModel.update(paasAppEntity);
            //应用是市场管理的话，刷新缓存
            String marketManagementAlias = SystemAppMenuEnum.MARKET_MANAGEMENT.getAlias();
            if(Objects.equals(paasAppEntity.getAlias(),marketManagementAlias)){
                setEnable2RedisByAlias(paasAppEntity.getCorpid(),marketManagementAlias,paasAppEntity.getEnable());
            }
            String corpid = applicationUpdateDTO.getCorpid();
            String userId = applicationUpdateDTO.getUserId();
            String userName = applicationUpdateDTO.getLoginUserName();
            // 记录日志
            String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_UPDATE_APP), userName, paasAppEntity.getName());
            JSONObject oldObj = JsonHelperUtil.parseObject(JSONObject.toJSONString(entity));
            JSONObject newObj = JsonHelperUtil.parseObject(JSONObject.toJSONString(paasAppEntity));
            List<DetailLogPojo> detailArr = logHelp.getDetailArr4Normal(corpid, OperateModuleTypeEnum.PAAS_APP, oldObj, newObj);
            mongoLogHelp.buildLog4DetailArr(detailArr, corpid, userId, userName, OperateModuleTypeEnum.PAAS_APP, OperateTypeEnum.EDIT, paasAppEntity.getId().toString(), paasAppEntity.getName(), memo, applicationUpdateDTO.getHttpHeader());

        } catch (XbbException e){
            throw e;
        } catch (Exception e) {
            LOG.error("paasApp数据库更新出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        ApplicationUpdateVO applicationUpdateVO = new ApplicationUpdateVO();
        applicationUpdateVO.setAppId(paasAppEntity.getId());
        return applicationUpdateVO;
    }
}
